package org.weso.lodin.dao;

import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;

import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.weso.lodin.exceptions.LodinModelException;
import org.weso.lodin.generated.CountryEnum;
import org.weso.lodin.generated.Dataset;
import org.weso.lodin.generated.TypeTable;
import org.weso.lodin.generated.TypeValues;
import org.weso.lodin.to.ObservationTO;
import org.weso.lodin.utils.POIUtils;
import org.weso.lodin.utils.StatusUtils;



public class PrimaryObservationDAOImpl implements ObservationDAO<ObservationTO>{

	public static final String RAW_DATA_PRIMARY = "Raw";
	public static final String NORMALISED_DATA_PRIMARY = "Normalised";
	protected static Logger logger = Logger.getLogger(PrimaryObservationDAOImpl.class);
	private HSSFWorkbook wb;

	public PrimaryObservationDAOImpl(InputStream data){
		try {			
			this.wb = new HSSFWorkbook(data);
			logger.info("Loading workbook");
		} catch (IOException e) {
			throw new LodinModelException(e, "Loading workbook");
		}
	}


	public List<ObservationTO> getObservations(List<Dataset> datasets) {		
		List<ObservationTO> observations = new LinkedList<ObservationTO>();
		for(Dataset dataset:datasets){
			observations.addAll(extractObservationsByDataset(dataset));
		}
		return observations;
	}


	private List<ObservationTO> extractObservationsByDataset(Dataset dataset) {
		List<ObservationTO> observations = new LinkedList<ObservationTO>();
		HSSFSheet sheet = wb.getSheet(dataset.getId().split("-")[1]);
		FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
		logger.info("Loading observations from dataset: "+dataset.getIndicator());
		for(TypeTable tableType:dataset.getTable()){
			int start = tableType.getRowStart().intValue();
			int end = tableType.getRowEnd().intValue();
			for(int rowIndex = start-1; rowIndex<end; rowIndex++){
				HSSFRow row = sheet.getRow(rowIndex);
				if (row == null) {
					continue;
				}				
				List<TypeValues> values = tableType.getValues();	
				for(TypeValues item:values){	
					int valueCol = Integer.parseInt(item.getValueCol());
					String dataType = item.getDatatype();
					String countryCol = item.getCountryCol();
					String countryValue = POIUtils.extractValue(
							row.getCell(ObservationDAOImpl.encode(countryCol)), 
							evaluator);
					CountryEnum countryType = CountryEnum.NAME ;//Constant
					String countryAltValue = "";//Constant
					CountryEnum countryAltType = CountryEnum.NAME;	//Constant				
					String value = POIUtils.extractValue(row.getCell(valueCol), evaluator);
					String year = ""+item.getYear().getYear();
					StatusUtils status = extractStatus(dataset, row, valueCol);			
					ObservationTO observation = new ObservationTO(
							"",
							dataType,
							countryValue, 
							countryType, 
							countryAltValue, 
							countryAltType, 
							value,
							year,
					"");
					observation.setDataset(dataset);
					observation.setStatus(status);
					observations.add(observation);
				}			
			}
		}
		return observations;
	}

	private StatusUtils extractStatus(Dataset dataset, HSSFRow row, int valueCol) {
		if(dataset.getId().split("-")[1].equals(RAW_DATA_PRIMARY)){
			return StatusUtils.NORMAL;		
		}else 	return StatusUtils.NORMALISED;
	
	}

	public List<ObservationTO> getObservationsByIndicator(
			Dataset dataset) {
		return extractObservationsByDataset(dataset);
	}




}
